package com.superiron.scaffold.core.util;

import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import lombok.extern.slf4j.Slf4j;

import java.time.*;
import java.time.temporal.ChronoUnit;
import java.time.temporal.TemporalAdjusters;
import java.util.Date;

/**
 * 日期转换
 */
@Slf4j
public abstract class DateFormatUtil {
	
	public static Date parseDate(String date, String format) {
		return DateUtil.parse(date, DatePattern.createFormatter(format)).toJdkDate();
	}
	
	public static String formatDateStr(Date date, String format) {
		return DateUtil.format(date, DatePattern.createFormatter(format));
	}
	
	/**
	 * 两个日期直接相差天数
	 * @param start
	 * @param end
	 * @return
	 */
	public static long betweenDays(Date start, Date end) {
		LocalDate startTime = dateToLocalDate(start);
		LocalDate endTime = dateToLocalDate(end);
		return endTime.toEpochDay() - startTime.toEpochDay();
	}
	
	/**
	 * 两个日期直接相差
	 * @param start
	 * @param end
	 * @return
	 */
	public static long betweenTime(Date start, Date end, ChronoUnit chronoUnit) {
		LocalDateTime startTime = dateToLocalDateTime(start);
		LocalDateTime endTime = dateToLocalDateTime(end);
		return startTime.until(endTime, chronoUnit);
	}
	
	
	// 01. java.util.Date --> java.time.LocalDateTime
	public static LocalDateTime dateToLocalDateTime(Date date) {
		Instant instant = date.toInstant();
		ZoneId zone = ZoneId.systemDefault();
		return LocalDateTime.ofInstant(instant, zone);
	}
	
	// 02. java.util.Date --> java.time.LocalDate
	public static LocalDate dateToLocalDate(Date date) {
		Instant instant = date.toInstant();
		ZoneId zone = ZoneId.systemDefault();
		LocalDateTime localDateTime = LocalDateTime.ofInstant(instant, zone);
		return localDateTime.toLocalDate();
	}
	
	// 03. java.util.Date --> java.time.LocalTime
	public static LocalTime dateToLocalTime(Date date) {
		Instant instant = date.toInstant();
		ZoneId zone = ZoneId.systemDefault();
		LocalDateTime localDateTime = LocalDateTime.ofInstant(instant, zone);
		return localDateTime.toLocalTime();
	}
	
	
	// 04. java.time.LocalDateTime --> java.util.Date
	public static Date localDateTimeToDate(LocalDateTime localDateTime) {
		ZoneId zone = ZoneId.systemDefault();
		Instant instant = localDateTime.atZone(zone).toInstant();
		return Date.from(instant);
	}
	
	
	// 05. java.time.LocalDate --> java.util.Date
	public static Date localDateToDate(LocalDate localDate) {
		ZoneId zone = ZoneId.systemDefault();
		Instant instant = localDate.atStartOfDay().atZone(zone).toInstant();
		return Date.from(instant);
	}
	
	// 06. java.time.LocalTime --> java.util.Date
	public static Date localTimeToDate(LocalTime localTime, LocalDate localDate) {
		LocalDateTime localDateTime = LocalDateTime.of(localDate, localTime);
		ZoneId zone = ZoneId.systemDefault();
		Instant instant = localDateTime.atZone(zone).toInstant();
		return Date.from(instant);
	}
	
	/**
	 * 获取当前时间几天内的时间
	 *
	 * @param : [num：+1往后加-1往前减, isFirst: true 表示开始时间，false表示结束时间]
	 * @return
	 */
	public static LocalDateTime getStartOrEndDayOfDay(Integer num, Boolean isFirst) {
		LocalDate resDate = LocalDate.now();
		if (num != null && num != 0) {
			resDate = resDate.plusDays(num);
		}
		LocalDateTime resultTime;
		if (isFirst) {
			resultTime = LocalDateTime.of(resDate, LocalTime.MIN);
		} else {
			resultTime = LocalDateTime.of(resDate, LocalTime.MAX);
		}
		return resultTime;
	}
	
	/**
	 * 获取本周的第一天或最后一天
	 *
	 * @param : [today, isFirst: true 表示开始时间，false表示结束时间]
	 * @return
	 */
	public static LocalDateTime getStartOrEndDayOfWeek(LocalDate today, Integer weekNum, Boolean isFirst) {
		LocalDate resDate = LocalDate.now();
		if (today == null) {
			today = resDate;
		}
		LocalDateTime resultTime;
		DayOfWeek week = today.getDayOfWeek();
		int value = week.getValue();
		if (isFirst) {
			resDate = today.minusDays(value - 1).plusDays(weekNum * 7);
			resultTime = LocalDateTime.of(resDate, LocalTime.MIN);
		} else {
			resDate = today.plusDays(7 - value).plusDays(weekNum * 7);;
			resultTime = LocalDateTime.of(resDate, LocalTime.MAX);
		}
		return resultTime;
	}
	
	/**
	 * 获取本月的第一天或最后一天
	 *
	 * @Param: [today, isFirst: true 表示开始时间，false表示结束时间]
	 * @return
	 */
	public static LocalDateTime getStartOrEndDayOfMonth(LocalDate today, Integer monthNum, Boolean isFirst) {
		LocalDate resDate = LocalDate.now();
		if (today == null) {
			today = resDate;
		}
		if (monthNum != null && monthNum != 0) {
			today = today.plusMonths(monthNum);
		}
		LocalDateTime resultTime;
		if (isFirst) {
			resDate = today.with(TemporalAdjusters.firstDayOfMonth());
			resultTime = LocalDateTime.of(resDate, LocalTime.MIN);
		} else {
			resDate = today.with(TemporalAdjusters.lastDayOfMonth());
			resultTime = LocalDateTime.of(resDate, LocalTime.MAX);
		}
		return resultTime;
	}
	
	/**
	 * 获取本季度的第一天或最后一天
	 *
	 * @param : [today, isFirst: true 表示开始时间，false表示结束时间]
	 * @return
	 */
	public static LocalDateTime getStartOrEndDayOfQuarter(LocalDate today, Boolean isFirst) {
		LocalDate resDate = LocalDate.now();
		if (today == null) {
			today = resDate;
		}
		LocalDateTime resultTime;
		
		Month month = today.getMonth();
		Month firstMonthOfQuarter = month.firstMonthOfQuarter();
		Month endMonthOfQuarter = Month.of(firstMonthOfQuarter.getValue() + 2);
		if (isFirst) {
			resDate = LocalDate.of(today.getYear(), firstMonthOfQuarter, 1);
			resultTime = LocalDateTime.of(resDate, LocalTime.MIN);
		} else {
			resDate = LocalDate.of(today.getYear(), endMonthOfQuarter, endMonthOfQuarter.length(today.isLeapYear()));
			resultTime = LocalDateTime.of(resDate, LocalTime.MAX);
		}
		return resultTime;
	}
	
	/**
	 * 获取本年的第一天或最后一天
	 *
	 * @param : [today, isFirst: true 表示开始时间，false表示结束时间]
	 * @return
	 */
	public static LocalDateTime getStartOrEndDayOfYear(LocalDate today, Integer yearNum, Boolean isFirst) {
		LocalDate resDate = LocalDate.now();
		LocalDateTime resultTime;
		if (today == null) {
			today = resDate;
		}
		if (yearNum != null && yearNum != 0) {
			today = today.plusYears(yearNum);
		}
		if (isFirst) {
			resDate = today.with(TemporalAdjusters.firstDayOfYear());
			resultTime = LocalDateTime.of(resDate, LocalTime.MIN);
		} else {
			resDate = today.with(TemporalAdjusters.lastDayOfYear());
			resultTime = LocalDateTime.of(resDate, LocalTime.MAX);
		}
		return resultTime;
	}
	
	public static int compareNowDate(Date date){
		return compareDate(date, new Date());
	}
	
	/**
	 *
	 * @param dt1 传入的时间
	 * @param dt2 当前时间
	 * @return    设定文件
	 * @return int 1 说明传入的时间 大于当前时间；0 传入的时间 等于 当前时间；-1 传入的时间小于当前时间
	 * @throws
	 */
	public static int compareDate(Date dt1, Date dt2) {
		try {
			if (dt1.getTime() > dt2.getTime()) {
				return 1;
			} else if (dt1.getTime() < dt2.getTime()) {
				return -1;
			} else {
				return 0;
			}
		} catch (Exception exception) {
			exception.printStackTrace();
		}
		return 0;
	}
	
	public static void main(String args[]){
		System.out.println(getStartOrEndDayOfYear(null,-1, true));
		System.out.println(getStartOrEndDayOfYear(LocalDate.now(),-1, false));
		System.out.println(getStartOrEndDayOfYear(null,0, true));
		System.out.println(getStartOrEndDayOfYear(LocalDate.now(),0, false));
		System.out.println(getStartOrEndDayOfYear(LocalDate.now(),1, true));
		System.out.println(getStartOrEndDayOfYear(LocalDate.now(),1, false));
	}
}
